/**
 *
 * 用户路由件
 *
 * all/get/post/delete/put 是路由件目前所完全支持的方法
 * 匹配表达式直接作为方法对象的key，触发方法直接作为方法对象的value
 * 我们把每个表达式对应的方法称作为触发方法，这个方法只有两个传入参数
 * ctx 基于原koa2上扩展的功能对象，支持原koa2所有ctx方法
 * next 返回它能够跳过触发函数进入下一个匹配表达式的触发函数
 * ctx {
 * 	hd	处理件对象，通过它去调用对应处理件内方法
 * 	common 工具类
 * 	config 配置数据
 * 	fs 文件操作模块
 * 	uploader 上传文件处理模块
 * 	mysql 数据库连接池，通过它去调用对应连接的操作方法
 * 	redis Redis数据库连接池，通过它去调用对应连接的操作方法
 * 	cron 定时任务池，通过它操作对应定时任务
 * }
 * 
 * 注意事项：
 * 触发方法应该加上async关键字，否则框架可能无法正确同步的返回数据
 * 调用处理件方法时，如果处理件方法使用了async关键字请务必保证加上await关键字等到此方法完成返回
 *
 */

module.exports = {
	get: {

		//检查登录状态 type session
		'/user/checkLogin': async ctx => {
			const {session} = await ctx.auth.allow('normal', 'student', 'teacher', 'inside')
			return await ctx.hd.user.checkLogin(session)
		},

		//获取正方验证码
		'/user/zfVCode': async ctx => {
			await ctx.auth.allow('normal')
			return await ctx.hd.zf.getVCode(ctx.user)
		},

		//获取待接单维修订单
		'/user/repair/waitOrder': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const waitList = await ctx.hd.repair.getWaitRepairOrderListByUserIdCache(userId)
			if(waitList)
				return waitList
			return await ctx.hd.repair.getWaitRepairOrderListByUserId(userId)
		},

		//获取已接单维修订单
		'/user/repair/acceptOrder': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const acceptList = await ctx.hd.repair.getAcceptRepairOrderListByUserIdCache(userId)
			if(acceptList)
				return acceptList
			return await ctx.hd.repair.getAcceptRepairOrderListByUserId(userId)
		},

		//获取已完成维修订单
		'/user/repair/finishOrder': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const finishList = await ctx.hd.repair.getFinishRepairOrderListByUserIdCache(userId)
			if(finishList)
				return finishList
			return await ctx.hd.repair.getFinishRepairOrderListByUserId(userId)
		},

		//获取失物招领待审核列表
		'/user/lost/waitRecord': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const lostRecordList = await ctx.hd.lost.getWaitRecordListByUserIdCache(userId)
			if(lostRecordList)
				return lostRecordList
			return await ctx.hd.lost.getWaitRecordListByUserId(userId)
		},

		//获取失物招领已发布列表
		'/user/lost/publishRecord': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const lostRecordList = await ctx.hd.lost.getPublishRecordListByUserIdCache(userId)
			if(lostRecordList)
				return lostRecordList
			return await ctx.hd.lost.getPublishRecordListByUserId(userId)
		},

		//获取失物招领已完成列表
		'/user/lost/finishRecord': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const lostRecordList = await ctx.hd.lost.getFinishRecordListByUserIdCache(userId)
			if(lostRecordList)
				return lostRecordList
			return await ctx.hd.lost.getFinishRecordListByUserId(userId)
		},

		//获取失物列表
		'/user/lost': async ctx => {
			await ctx.auth.allow('student', 'teacher', 'inside')
			const {start, count} = ctx.queryData
			const lostList = await ctx.hd.lost.getLostListCache(start, count)
			if(lostList)
				return lostList
			return await ctx.hd.lost.getLostList(start, count)
		},

		//获取失物详情
		'/user/lost/:id': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const {id} = ctx.params
			const lostData = await ctx.hd.lost.getLostDataCache(id, userId)
			if(lostData)
				return lostData
			return await ctx.hd.lost.getLostData(id, userId)
		}

	},
	post: {

		//登录
		'/user/login/wx': async ctx => {
			await ctx.auth.allow('nosign')
			const {wxCode, wxEncrypytedData, wxIv} = ctx.bodyData
			return await ctx.hd.user.wxLogin({wxCode, wxEncrypytedData, wxIv})
		},

		//创新盒子授权登录
		'/user/login/auth/:appId': async ctx => {
			const {userId, type} = await ctx.auth.allow('student', 'teacher', 'inside')
			const {appId} = ctx.params
			if(!/^[a-z]\-[0-9]{4}$/.test(appId))
				return ctx.error('-2104', 'appId invalid')
			return await ctx.hd.user.authLogin(appId, type, userId)
		},

		//用户反馈
		'/user/feedback': async ctx => {
			const {userId} = await ctx.auth.allow('normal', 'student', 'teacher', 'inside')
			const {content, contact} = ctx.bodyData
			const feedbackId = await ctx.hd.sys.addFeedback(ctx.user.userId, content, contact)
			return feedbackId
		},

		//创建维修订单
		'/user/repair/order': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const { repairType, repairContent, uploadIdList = [], repairAddress, repairContact } = ctx.bodyData
			if(!ctx.hd.repair.checkFields('repairType', repairType))
				return ctx.error('-2075', 'repair type invalid')
			if(!repairContent || repairContent.length > 200)
				return ctx.error('-2076', 'repair content invalid')
			if(!uploadIdList instanceof Array || uploadIdList.length > 3)
				return ctx.error('-2077', 'repair photo list invalid')
			if(!repairAddress || repairAddress.length > 120)
				return ctx.error('-2078', 'repair address invalid')
			if(!repairContact || repairContact.length > 60)
				return ctx.error('-2079', 'repair contact invalid')
			const {repairOpen} = await ctx.hd.sys.getCommonData('repairOpen')
			if(repairOpen == 0)
				return ctx.error('-2102', 'repair is not open')
			return await ctx.hd.repair.createRepairOrder(userId, repairType, repairContent, uploadIdList, repairAddress, repairContact)
		},

		//评价维修订单
		'/user/repair/order/:repairId/evaluate': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const {repairId} = ctx.params
			const {repairEvaluateStar, repairEvaluateContent} = ctx.bodyData
			if(!ctx.hd.repair.checkFields('repairId', repairId))
				return ctx.error('-2080', 'repair id invalid')
			if(isNaN(repairEvaluateStar) || repairEvaluateStar == 0 || repairEvaluateStar > 5)
				return ctx.error('-2081', 'repair evaluate star value invalid')
			if(repairEvaluateContent > 200)
				return ctx.error('-2082', 'repair evaluate content invalid')
			await ctx.hd.repair.addRepairEvaluate(repairId, repairEvaluateStar, repairEvaluateContent)
			await ctx.hd.repair.clearFinishRepairOrderListByUserIdCache(userId)
			return 1
		},

		//添加失物招领
		'/user/lost/goods': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const {lostTitle, lostContent, lostAddress, lostContact, uploadIdList = []} = ctx.bodyData
			if(!lostTitle || lostTitle.length > 60)
				return ctx.error('-2094', 'lost title invalid')
			if(!lostContent || lostContent.length > 300)
				return ctx.error('-2095', 'lost content invalid')
			if(!lostAddress || lostAddress.length > 60)
				return ctx.error('-2096', 'lost address invalid')
			if(!lostContact || lostContact.length > 150)
				return ctx.error('-2097', 'lost contact invalid')
			if(!uploadIdList instanceof Array || uploadIdList.length > 3)
				return ctx.error('-2098', 'lost photo list invalid')
			const lostId = await ctx.hd.lost.addLostGoods(userId, lostTitle, lostContent, lostAddress, lostContact, uploadIdList)
			return lostId
		},

		//添加寻物启事
		'/user/lost/record': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const {lostTitle, lostContent, lostAddress, lostContact, uploadIdList = []} = ctx.bodyData
			if(!lostTitle || lostTitle.length > 60)
				return ctx.error('-2089', 'lost title invalid')
			if(!lostContent || lostContent.length > 300)
				return ctx.error('-2090', 'lost content invalid')
			if(!lostAddress || lostAddress.length > 60)
				return ctx.error('-2091', 'lost address invalid')
			if(!lostContact || lostContact.length > 150)
				return ctx.error('-2092', 'lost contact invalid')
			if(!uploadIdList instanceof Array || uploadIdList.length > 3)
				return ctx.error('-2093', 'lost photo list invalid')
			const lostId = await ctx.hd.lost.addLostRecord(userId, lostTitle, lostContent, lostAddress, lostContact, uploadIdList)
			return lostId
		}

	},
	put: {

		//获取最新待接单维修订单
		'/user/repair/waitOrder': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			return await ctx.hd.repair.getWaitRepairOrderListByUserId(userId)
		},

		//获取最新已接单维修订单
		'/user/repair/acceptOrder': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			return await ctx.hd.repair.getAcceptRepairOrderListByUserId(userId)
		},

		//获取最新已完成维修订单
		'/user/repair/finishOrder': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			return await ctx.hd.repair.getFinishRepairOrderListByUserId(userId)
		},

		//获取最新失物招领待审核列表
		'/user/lost/waitRecord': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			return await ctx.hd.lost.getWaitRecordListByUserId(userId)
		},

		//获取最新失物招领已发布列表
		'/user/lost/publishRecord': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			return await ctx.hd.lost.getPublishRecordListByUserId(userId)
		},

		//获取最新失物招领已完成列表
		'/user/lost/finishRecord': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			return await ctx.hd.lost.getFinishRecordListByUserId(userId)
		},

		//获取最新失物列表
		'/user/lost': async ctx => {
			await ctx.auth.allow('student', 'teacher', 'inside')
			const {start, count} = ctx.bodyData
			return await ctx.hd.lost.getLostList(start, count)
		},

		//获取最新失物详情
		'/user/lost/:id': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const {id} = ctx.params
			return await ctx.hd.lost.getLostData(id, userId)
		},

		//结束失物招领
		'/user/lost/:id/finish': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const {id} = ctx.params
			return await ctx.hd.lost.updateLostFinishStatus(id, userId, 1)
		}
		
	},
	delete: {

		//删除失物招领项
		'/user/lost/:id': async ctx => {
			const {userId} = await ctx.auth.allow('student', 'teacher', 'inside')
			const {id} = ctx.params
			return await ctx.hd.lost.delLostData(id, userId)
		}

	},
	upload: {
		image: {

			'/user/repair/photo/upload': async ctx => {
				const {filename, path} = ctx.file
				console.log(`upload repair file: ${filename}`)
				return filename
			},

			'/user/lost/photo/upload': async ctx => {
				const {filename, path} = ctx.file
				console.log(`upload lost file: ${filename}`)
				return filename
			}

		}
	}
}